// xstddef internal header
#ifndef _XSTDDEF_
#define _XSTDDEF_
#include <cstddef>
#include <cstdlib>

 #if _HAS_INITIALIZER_LISTS
#include <initializer_list>
 #endif /* _HAS_INITIALIZER_LISTS */

#include <xtr1common>

 #if _HAS_CPP0X
  #define _EQ_VOID	= void

 #else /* _HAS_CPP0X */
  #define _EQ_VOID
 #endif /* _HAS_CPP0X */

 #if !defined(_XSTD)
  #define _X_STD_BEGIN	_STD_BEGIN
  #define _X_STD_END	_STD_END
  #define _XSTD	_STD /* LEAVE SPACE */
 #endif /* !defined(_XSTD) */

_STD_BEGIN
		// EXCEPTION MACROS
 #ifndef _THROWS

 #if _HAS_EXCEPTIONS

 #if _HAS_NOEXCEPT
  #define _THROWS(x)

 #else /* _HAS_NOEXCEPT */
  #define _THROWS(x)	throw (x)
 #endif /* _HAS_NOEXCEPT */

 #else /* _HAS_EXCEPTIONS */
  #define _THROWS(x)
 #endif /* _HAS_EXCEPTIONS */

 #endif /* _THROWS */

 #if _HAS_EXCEPTIONS
 #define _TRY_BEGIN	try {
 #define _CATCH(x)	} catch (x) {
 #define _CATCH_ALL	} catch (...) {
 #define _CATCH_END	}

 #define _RAISE(x)	throw x
 #define _RERAISE	throw

 #if _HAS_NOEXCEPT
  #define _THROW0()		noexcept

 #else /* _HAS_NOEXCEPT */
  #define _THROW0()		throw ()
 #endif /* _HAS_NOEXCEPT */

  #define _THROW1(x)	throw x

  #define _THROW(x, y)		throw x(y)
  #define _THROW_NCEE(x, y)	throw x(y)

 #else /* _HAS_EXCEPTIONS */
 #define _TRY_BEGIN	{ if (1) {
 #define _CATCH(x)	} else if (0) {
 #define _CATCH_ALL	} else if (0) {
 #define _CATCH_END	} }

  #define _RAISE(x)	_XSTD _Throw(x)

 #define _RERAISE

 #define _THROW0()
 #define _THROW1(x)
 #define _THROW(x, y)		x(y)._Raise()
 #define _THROW_NCEE(x, y)	x(y)._Raise()
 #endif /* _HAS_EXCEPTIONS */

		// MISCELLANEOUS MACROS
#define _EMPTY_ARGUMENT		/* for empty macro argument */

		// BITMASK MACROS
 #define _BITMASK(Enum, Ty)	typedef Enum Ty

#if defined(__CODEGEARC__) && defined(__clang__) && !_HAS_CONSTEXPR
#define _CONSTEXPR constexpr
#else
#define _CONSTEXPR
#endif

 #define _BITMASK_OPS(Ty) \
inline Ty& operator&=(Ty& _Left, Ty _Right) \
	{	/* return _Left &= _Right */ \
	_Left = (Ty)((int)_Left & (int)_Right); return (_Left); \
	} \
\
inline Ty& operator|=(Ty& _Left, Ty _Right) \
	{	/* return _Left |= _Right */ \
	_Left = (Ty)((int)_Left | (int)_Right); return (_Left); \
	} \
\
inline Ty& operator^=(Ty& _Left, Ty _Right) \
	{	/* return _Left ^= _Right */ \
	_Left = (Ty)((int)_Left ^ (int)_Right); return (_Left); \
	} \
\
_CONSTEXPR inline _CONST_FUN Ty operator&(Ty _Left, Ty _Right) \
	{	/* return _Left & _Right */ \
	return ((Ty)((int)_Left & (int)_Right)); \
	} \
\
_CONSTEXPR inline _CONST_FUN Ty operator|(Ty _Left, Ty _Right) \
	{	/* return _Left | _Right */ \
	return ((Ty)((int)_Left | (int)_Right)); \
	} \
\
_CONSTEXPR inline _CONST_FUN Ty operator^(Ty _Left, Ty _Right) \
	{	/* return _Left ^ _Right */ \
	return ((Ty)((int)_Left ^ (int)_Right)); \
	} \
\
_CONSTEXPR inline _CONST_FUN Ty operator~(Ty _Left) \
	{	/* return ~_Left */ \
	return ((Ty)~(int)_Left); \
	}

		// TYPE DEFINITIONS
template<bool,
	class _Ty1,
	class _Ty2>
	struct _If
	{	// type is _Ty2 for assumed false
	typedef _Ty2 type;
	};

template<class _Ty1,
	class _Ty2>
	struct _If<true, _Ty1, _Ty2>
	{	// type is _Ty1 for assumed true
	typedef _Ty1 type;
	};

template<class _Ty>
	struct _Always_false
	{	// false value that probably won't be optimized away
	static const bool value = false;
	};

 #ifndef _STATIC_ASSERT2
  #define _STATIC_ASSERT2(test, mesg)	\
	((void)_STD _Static_assert<test>(mesg))

template<bool>
	struct _Static_assert;	// leave false undefined

template<>
	struct _Static_assert<true>
	{	// assertion is met
	_Static_assert(const char *)
		{	// construct from message
		};
	};
 #endif /* _STATIC_ASSERT2 */

		//	FUNCTIONAL STUFF (from <functional>)
		// TEMPLATE STRUCT unary_function
template<class _Arg,
	class _Result>
	struct unary_function
	{	// base class for unary functions
	typedef _Arg argument_type;
	typedef _Result result_type;
	};

		// TEMPLATE STRUCT binary_function
template<class _Arg1,
	class _Arg2,
	class _Result>
	struct binary_function
	{	// base class for binary functions
	typedef _Arg1 first_argument_type;
	typedef _Arg2 second_argument_type;
	typedef _Result result_type;
	};

		// TEMPLATE STRUCT plus
template<class _Ty _EQ_VOID>
	struct plus
	{	// functor for operator+
	typedef _Ty first_argument_type;
	typedef _Ty second_argument_type;
	typedef _Ty result_type;

	_CONST_FUN _Ty operator()(const _Ty& _Left, const _Ty& _Right) const
		{	// apply operator+ to operands
		return (_Left + _Right);
		}
	};

		// TEMPLATE STRUCT minus
template<class _Ty _EQ_VOID>
	struct minus
	{	// functor for operator-
	typedef _Ty first_argument_type;
	typedef _Ty second_argument_type;
	typedef _Ty result_type;

	_CONST_FUN _Ty operator()(const _Ty& _Left, const _Ty& _Right) const
		{	// apply operator- to operands
		return (_Left - _Right);
		}
	};

		// TEMPLATE STRUCT multiplies
template<class _Ty _EQ_VOID>
	struct multiplies
	{	// functor for operator*
	typedef _Ty first_argument_type;
	typedef _Ty second_argument_type;
	typedef _Ty result_type;

	_CONST_FUN _Ty operator()(const _Ty& _Left, const _Ty& _Right) const
		{	// apply operator* to operands
		return (_Left * _Right);
		}
	};

		// TEMPLATE STRUCT equal_to
template<class _Ty _EQ_VOID>
	struct equal_to
	{	// functor for operator==
	typedef _Ty first_argument_type;
	typedef _Ty second_argument_type;
	typedef bool result_type;

	_CONST_FUN bool operator()(const _Ty& _Left, const _Ty& _Right) const
		{	// apply operator== to operands
		return (_Left == _Right);
		}
	};

		// TEMPLATE STRUCT less
template<class _Ty _EQ_VOID>
	struct less
	{	// functor for operator<
	typedef _Ty first_argument_type;
	typedef _Ty second_argument_type;
	typedef bool result_type;

	_CONST_FUN bool operator()(const _Ty& _Left, const _Ty& _Right) const
		{	// apply operator< to operands
		return (_Left < _Right);
		}
	};

 #if _HAS_CPP0X
		// is_transparent MACHINERY
typedef int _Is_trans;	// type for is_transparent

		// TEMPLATE STRUCT SPECIALIZATION plus
template<>
	struct plus<void>
	{	// transparent functor for operator+
	typedef _Is_trans is_transparent;

	template<class _Ty1,
		class _Ty2>
		_CONST_FUN auto operator()(_Ty1&& _Left, _Ty2&& _Right) const
		-> decltype(static_cast<_Ty1 _REFREF>(_Left)
			+ static_cast<_Ty2 _REFREF>(_Right))
		{	// transparently apply operator+ to operands
		return (static_cast<_Ty1 _REFREF>(_Left)
			+ static_cast<_Ty2 _REFREF>(_Right));
		}
	};

		// TEMPLATE STRUCT SPECIALIZATION minus
template<>
	struct minus<void>
	{	// transparent functor for operator-
	typedef _Is_trans is_transparent;

	template<class _Ty1,
		class _Ty2>
		_CONST_FUN auto operator()(_Ty1&& _Left, _Ty2&& _Right) const
		-> decltype(static_cast<_Ty1 _REFREF>(_Left)
			- static_cast<_Ty2 _REFREF>(_Right))
		{	// transparently apply operator- to operands
		return (static_cast<_Ty1 _REFREF>(_Left)
			- static_cast<_Ty2 _REFREF>(_Right));
		}
	};

		// TEMPLATE STRUCT SPECIALIZATION multiplies
template<>
	struct multiplies<void>
	{	// transparent functor for operator*
	typedef _Is_trans is_transparent;

	template<class _Ty1,
		class _Ty2>
		_CONST_FUN auto operator()(_Ty1&& _Left, _Ty2&& _Right) const
		-> decltype(static_cast<_Ty1 _REFREF>(_Left)
			* static_cast<_Ty2 _REFREF>(_Right))
		{	// transparently apply operator* to operands
		return (static_cast<_Ty1 _REFREF>(_Left)
			* static_cast<_Ty2 _REFREF>(_Right));
		}
	};

		// TEMPLATE STRUCT SPECIALIZATION equal_to
template<>
	struct equal_to<void>
	{	// transparent functor for operator==
	typedef _Is_trans is_transparent;

	template<class _Ty1,
		class _Ty2>
		_CONST_FUN auto operator()(_Ty1&& _Left, _Ty2&& _Right) const
		-> decltype(static_cast<_Ty1 _REFREF>(_Left)
			== static_cast<_Ty2 _REFREF>(_Right))
		{	// transparently apply operator== to operands
		return (static_cast<_Ty1 _REFREF>(_Left)
			== static_cast<_Ty2 _REFREF>(_Right));
		}
	};

		// TEMPLATE STRUCT SPECIALIZATION less
template<>
	struct less<void>
	{	// transparent functor for operator<
	typedef _Is_trans is_transparent;

	template<class _Ty1,
		class _Ty2>
		_CONST_FUN auto operator()(_Ty1&& _Left, _Ty2&& _Right) const
		-> decltype(static_cast<_Ty1 _REFREF>(_Left)
			< static_cast<_Ty2 _REFREF>(_Right))
		{	// transparently apply operator< to operands
		return (static_cast<_Ty1 _REFREF>(_Left)
			< static_cast<_Ty2 _REFREF>(_Right));
		}
	};

#define _FUNCTOR(func, iter)	func<>()

 #else /* _HAS_CPP0X */
#define _FUNCTOR_IMPL(func) template<class _Ty> inline \
	func<_Ty> _Functor_ ## func(_Ty *) \
		{return (func<_Ty>());}
#define _FUNCTOR(func, iter)	_Functor_ ##func(_Val_type(iter))

_FUNCTOR_IMPL(plus)
_FUNCTOR_IMPL(minus)
_FUNCTOR_IMPL(multiplies)
_FUNCTOR_IMPL(equal_to)
_FUNCTOR_IMPL(less)
 #endif /* _HAS_CPP0X */
_STD_END

#ifndef _HASH_SEQ_DEFINED
#define _HASH_SEQ_DEFINED
namespace std {
	// FUNCTION _Hash_seq
inline size_t _Hash_seq(const unsigned char *_First, size_t _Count)
	{	// FNV-1a hash function for bytes in [_First, _First + _Count)
  #if defined(_M_X64) || defined(_LP64) || defined(__x86_64)
	_STATIC_ASSERT2(sizeof(size_t) == 8, "This code is for 64-bit size_t.");
	const size_t _FNV_offset_basis = 14695981039346656037ULL;
	const size_t _FNV_prime = 1099511628211ULL;

 #else /* defined(_M_X64), etc. */
	static_assert(sizeof(size_t) == 4, "This code is for 32-bit size_t.");
	const size_t _FNV_offset_basis = 2166136261U;
	const size_t _FNV_prime = 16777619U;
  #endif /* defined(_M_X64), etc. */

	size_t _Val = _FNV_offset_basis;
	for (size_t _Next = 0; _Next < _Count; ++_Next)
		{	// fold in another byte
		_Val ^= (size_t)_First[_Next];
		_Val *= _FNV_prime;
		}
	return (_Val);
	}

	// TEMPLATE STRUCT _Bitwise_hash
template<class _Kty>
	struct _Bitwise_hash
	{	// hash functor for plain old data
	typedef _Kty argument_type;
	typedef size_t result_type;

	size_t operator()(const _Kty& _Keyval) const
		{	// hash _Keyval to size_t value by pseudorandomizing transform
		return (_Hash_seq((const unsigned char *)&_Keyval, sizeof (_Kty)));
		}
	};

	// TEMPLATE STRUCT hash
template<class _Kty>
	struct hash
		: public _Bitwise_hash<_Kty>
	{	// hash functor for enums
	};
template<>
	struct hash<bool>
		: public _Bitwise_hash<bool>
	{	// hash functor for bool
	};

template<>
	struct hash<char>
		: public _Bitwise_hash<char>
	{	// hash functor for char
	};

template<>
	struct hash<signed char>
		: public _Bitwise_hash<signed char>
	{	// hash functor for signed char
	};

template<>
	struct hash<unsigned char>
		: public _Bitwise_hash<unsigned char>
	{	// hash functor for unsigned char
	};

 #if _HAS_CHAR16_T_LANGUAGE_SUPPORT
template<>
	struct hash<char16_t>
		: public _Bitwise_hash<char16_t>
	{	// hash functor for char16_t
	};

template<>
	struct hash<char32_t>
		: public _Bitwise_hash<char32_t>
	{	// hash functor for char32_t
	};
 #endif /* _HAS_CHAR16_T_LANGUAGE_SUPPORT */

template<>
	struct hash<wchar_t>
		: public _Bitwise_hash<wchar_t>
	{	// hash functor for wchar_t
	};

template<>
	struct hash<short>
		: public _Bitwise_hash<short>
	{	// hash functor for short
	};

template<>
	struct hash<unsigned short>
		: public _Bitwise_hash<unsigned short>
	{	// hash functor for unsigned short
	};

template<>
	struct hash<int>
		: public _Bitwise_hash<int>
	{	// hash functor for int
	};

template<>
	struct hash<unsigned int>
		: public _Bitwise_hash<unsigned int>
	{	// hash functor for unsigned int
	};

template<>
	struct hash<long>
		: public _Bitwise_hash<long>
	{	// hash functor for long
	};

template<>
	struct hash<unsigned long>
		: public _Bitwise_hash<unsigned long>
	{	// hash functor for unsigned long
	};

template<>
	struct hash<long long>
		: public _Bitwise_hash<long long>
	{	// hash functor for long long
	};

template<>
	struct hash<unsigned long long>
		: public _Bitwise_hash<unsigned long long>
	{	// hash functor for unsigned long long
	};

template<>
	struct hash<float>
		: public _Bitwise_hash<float>
	{	// hash functor for float
	typedef float _Kty;
	typedef _Bitwise_hash<_Kty> _Mybase;

	size_t operator()(const _Kty& _Keyval) const
		{	// hash _Keyval to size_t value by pseudorandomizing transform
		return (_Mybase::operator()(
			_Keyval == 0 ? 0 : _Keyval));	// map -0 to 0
		}
	};

template<>
	struct hash<double>
		: public _Bitwise_hash<double>
	{	// hash functor for double
	typedef double _Kty;
	typedef _Bitwise_hash<_Kty> _Mybase;

	size_t operator()(const _Kty& _Keyval) const
		{	// hash _Keyval to size_t value by pseudorandomizing transform
		return (_Mybase::operator()(
			_Keyval == 0 ? 0 : _Keyval));	// map -0 to 0
		}
	};

template<>
	struct hash<long double>
		: public _Bitwise_hash<long double>
	{	// hash functor for long double
	typedef long double _Kty;
	typedef _Bitwise_hash<_Kty> _Mybase;

	size_t operator()(const _Kty& _Keyval) const
		{	// hash _Keyval to size_t value by pseudorandomizing transform
		return (_Mybase::operator()(
			_Keyval == 0 ? 0 : _Keyval));	// map -0 to 0
		}
	};

template<class _Ty>
	struct hash<_Ty *>
		: public _Bitwise_hash<_Ty *>
	{	// hash functor for _Ty *
	};
}	// namespace std

 #if 0 < _ALT_NS
_STD_BEGIN
using std::hash;
using std::_Hash_seq;
_STD_END
 #endif /* 0 < _ALT_NS */

#endif /* _HASH_SEQ_DEFINED */

 #if _HAS_TR1_IMPORTS
_STD_BEGIN
namespace tr1 {	// TR1 ADDITIONS
using _STD hash;
}	// namespace tr1
_STD_END
 #endif /* _HAS_TR1_IMPORTS */

#define _MEMBER_CALL_CV(FUNC, REF_OPT) \
	FUNC(, , REF_OPT) \
	FUNC(, const, REF_OPT) \
	FUNC(, volatile, REF_OPT) \
	FUNC(, const volatile, REF_OPT)

#define _NON_MEMBER_CALL(FUNC) \
	FUNC(_EMPTY_ARGUMENT)

 #if _HAS_REF_QUALIFIER
#define _MEMBER_CALL_CV_REF(FUNC) \
	_MEMBER_CALL_CV(FUNC, ) \
	_MEMBER_CALL_CV(FUNC, &) \
	_MEMBER_CALL_CV(FUNC, &&)

 #else /* _HAS_REF_QUALIFIER */
#define _MEMBER_CALL_CV_REF(FUNC) \
	_MEMBER_CALL_CV(FUNC, )
 #endif /* _HAS_REF_QUALIFIER */

#define _CLASS_DEFINE_CONST(CLASS) \
	CLASS(_EMPTY_ARGUMENT) \
	CLASS(const)

#define _CLASS_DEFINE_CV(CLASS) \
	CLASS(_EMPTY_ARGUMENT) \
	CLASS(const) \
	CLASS(volatile) \
	CLASS(const volatile)

 #if _HAS_REF_QUALIFIER
#define _CLASS_DEFINE_CV_REF(CLASS) \
	CLASS( , ) \
	CLASS(const, ) \
	CLASS(volatile, ) \
	CLASS(const volatile, ) \
	CLASS( , &) \
	CLASS(const, &) \
	CLASS(volatile, &) \
	CLASS(const volatile, &) \
	CLASS( , &&) \
	CLASS(const, &&) \
	CLASS(volatile, &&) \
	CLASS(const volatile, &&)

 #else /* _HAS_REF_QUALIFIER */
#define _CLASS_DEFINE_CV_REF(CLASS) \
	CLASS( , ) \
	CLASS(const, ) \
	CLASS(volatile, ) \
	CLASS(const volatile, )
 #endif /* _HAS_REF_QUALIFIER */

#define _COMMA	,	/* for immediate commas in macro parameters */

 #if _HAS_VARIADIC_TEMPLATES

 #else /* _HAS_VARIADIC_TEMPLATES */
#define _EX_()
#define _EX__Comma()	,	/* expand deferred _Comma to , */
#define _EX(...)	_EX_##__VA_ARGS__()

	// _VARIADIC_EXPAND* MACROS

 #if !defined(_VARIADIC_MAX)
  #define _VARIADIC_MAX	5

 #elif _VARIADIC_MAX < 5 || 10 < _VARIADIC_MAX
  #error _VARIADIC_MAX must be between 5 and 10, inclusive
 #endif /* !defined(_VARIADIC_MAX) */

 #if _VARIADIC_MAX == 5
#define _VARIADIC_EXPAND_2X	_VARIADIC_EXPAND_25
#define _VARIADIC_EXPAND_ALT_0X	_VARIADIC_EXPAND_ALT_05
#define _VARIADIC_EXPAND_P1_2X	_VARIADIC_EXPAND_P1_25
#define _VARIADIC_EXPAND_0_1X(FUNC) \
	_VARIADIC_EXPAND_XX_15(FUNC, _VARIADIC_EXPAND_0)
#define _VARIADIC_EXPAND_XX_1X(FUNC, EXPAND) \
	_VARIADIC_EXPAND_XX_15(FUNC, EXPAND)
#define _VARIADIC_EXPAND_1X_1D(FUNC) \
	_VARIADIC_EXPAND_15_1D(FUNC)

#define _PAD_LIST0	_PAD_LIST0_5
#define _PAD_LIST1	_PAD_LIST0_4
#define _PAD_LIST2	_PAD_LIST0_3
#define _PAD_LIST3	_PAD_LIST0_2
#define _PAD_LIST4	_PAD_LIST0_1
#define _PAD_LIST5	_PAD_LIST0_0

 #elif _VARIADIC_MAX == 6
#define _VARIADIC_EXPAND_2X	_VARIADIC_EXPAND_26
#define _VARIADIC_EXPAND_ALT_0X	_VARIADIC_EXPAND_ALT_06
#define _VARIADIC_EXPAND_P1_2X	_VARIADIC_EXPAND_P1_26
#define _VARIADIC_EXPAND_0_1X(FUNC) \
	_VARIADIC_EXPAND_XX_16(FUNC, _VARIADIC_EXPAND_0)
#define _VARIADIC_EXPAND_XX_1X(FUNC, EXPAND) \
	_VARIADIC_EXPAND_XX_16(FUNC, EXPAND)
#define _VARIADIC_EXPAND_1X_1D(FUNC) \
	_VARIADIC_EXPAND_16_1D(FUNC)

#define _PAD_LIST0	_PAD_LIST0_6
#define _PAD_LIST1	_PAD_LIST0_5
#define _PAD_LIST2	_PAD_LIST0_4
#define _PAD_LIST3	_PAD_LIST0_3
#define _PAD_LIST4	_PAD_LIST0_2
#define _PAD_LIST5	_PAD_LIST0_1
#define _PAD_LIST6	_PAD_LIST0_0

 #elif _VARIADIC_MAX == 7
#define _VARIADIC_EXPAND_2X	_VARIADIC_EXPAND_27
#define _VARIADIC_EXPAND_ALT_0X	_VARIADIC_EXPAND_ALT_07
#define _VARIADIC_EXPAND_P1_2X	_VARIADIC_EXPAND_P1_27
#define _VARIADIC_EXPAND_0_1X(FUNC) \
	_VARIADIC_EXPAND_XX_17(FUNC, _VARIADIC_EXPAND_0)
#define _VARIADIC_EXPAND_XX_1X(FUNC, EXPAND) \
	_VARIADIC_EXPAND_XX_17(FUNC, EXPAND)
#define _VARIADIC_EXPAND_1X_1D(FUNC) \
	_VARIADIC_EXPAND_17_1D(FUNC)

#define _PAD_LIST0	_PAD_LIST0_7
#define _PAD_LIST1	_PAD_LIST0_6
#define _PAD_LIST2	_PAD_LIST0_5
#define _PAD_LIST3	_PAD_LIST0_4
#define _PAD_LIST4	_PAD_LIST0_3
#define _PAD_LIST5	_PAD_LIST0_2
#define _PAD_LIST6	_PAD_LIST0_1
#define _PAD_LIST7	_PAD_LIST0_0

 #elif _VARIADIC_MAX == 8
#define _VARIADIC_EXPAND_2X	_VARIADIC_EXPAND_28
#define _VARIADIC_EXPAND_ALT_0X	_VARIADIC_EXPAND_ALT_08
#define _VARIADIC_EXPAND_P1_2X	_VARIADIC_EXPAND_P1_28
#define _VARIADIC_EXPAND_0_1X(FUNC) \
	_VARIADIC_EXPAND_XX_18(FUNC, _VARIADIC_EXPAND_0)
#define _VARIADIC_EXPAND_XX_1X(FUNC, EXPAND) \
	_VARIADIC_EXPAND_XX_18(FUNC, EXPAND)
#define _VARIADIC_EXPAND_1X_1D(FUNC) \
	_VARIADIC_EXPAND_18_1D(FUNC)

#define _PAD_LIST0	_PAD_LIST0_8
#define _PAD_LIST1	_PAD_LIST0_7
#define _PAD_LIST2	_PAD_LIST0_6
#define _PAD_LIST3	_PAD_LIST0_5
#define _PAD_LIST4	_PAD_LIST0_4
#define _PAD_LIST5	_PAD_LIST0_3
#define _PAD_LIST6	_PAD_LIST0_2
#define _PAD_LIST7	_PAD_LIST0_1
#define _PAD_LIST8	_PAD_LIST0_0

 #elif _VARIADIC_MAX == 9
#define _VARIADIC_EXPAND_2X	_VARIADIC_EXPAND_29
#define _VARIADIC_EXPAND_ALT_0X	_VARIADIC_EXPAND_ALT_09
#define _VARIADIC_EXPAND_P1_2X	_VARIADIC_EXPAND_P1_29
#define _VARIADIC_EXPAND_0_1X(FUNC) \
	_VARIADIC_EXPAND_XX_19(FUNC, _VARIADIC_EXPAND_0)
#define _VARIADIC_EXPAND_XX_1X(FUNC, EXPAND) \
	_VARIADIC_EXPAND_XX_19(FUNC, EXPAND)
#define _VARIADIC_EXPAND_1X_1D(FUNC) \
	_VARIADIC_EXPAND_19_1D(FUNC)

#define _PAD_LIST0	_PAD_LIST0_9
#define _PAD_LIST1	_PAD_LIST0_8
#define _PAD_LIST2	_PAD_LIST0_7
#define _PAD_LIST3	_PAD_LIST0_6
#define _PAD_LIST4	_PAD_LIST0_5
#define _PAD_LIST5	_PAD_LIST0_4
#define _PAD_LIST6	_PAD_LIST0_3
#define _PAD_LIST7	_PAD_LIST0_2
#define _PAD_LIST8	_PAD_LIST0_1
#define _PAD_LIST9	_PAD_LIST0_0

 #elif _VARIADIC_MAX == 10
#define _VARIADIC_EXPAND_2X	_VARIADIC_EXPAND_2A
#define _VARIADIC_EXPAND_ALT_0X	_VARIADIC_EXPAND_ALT_0A
#define _VARIADIC_EXPAND_P1_2X	_VARIADIC_EXPAND_P1_2A
#define _VARIADIC_EXPAND_0_1X(FUNC) \
	_VARIADIC_EXPAND_XX_1A(FUNC, _VARIADIC_EXPAND_0)
#define _VARIADIC_EXPAND_XX_1X(FUNC, EXPAND) \
	_VARIADIC_EXPAND_XX_1A(FUNC, EXPAND)
#define _VARIADIC_EXPAND_1X_1D(FUNC) \
	_VARIADIC_EXPAND_1A_1D(FUNC)

#define _PAD_LIST0	_PAD_LIST0_10
#define _PAD_LIST1	_PAD_LIST0_9
#define _PAD_LIST2	_PAD_LIST0_8
#define _PAD_LIST3	_PAD_LIST0_7
#define _PAD_LIST4	_PAD_LIST0_6
#define _PAD_LIST5	_PAD_LIST0_5
#define _PAD_LIST6	_PAD_LIST0_4
#define _PAD_LIST7	_PAD_LIST0_3
#define _PAD_LIST8	_PAD_LIST0_2
#define _PAD_LIST9	_PAD_LIST0_1
#define _PAD_LIST10	_PAD_LIST0_0
 #endif /* _VARIADIC_MAX */

// call FUNC(TEMPLATE_LIST, PADDING_LIST, LIST, COMMA, X1, X2, X3, X4)
#define _VARIADIC_EXPAND_0(FUNC, X1, X2, X3, X4) \
FUNC(_TEM_LIST0, _PAD_LIST0, _RAW_LIST0, , X1, X2, X3, X4)

#define _VARIADIC_EXPAND_1(FUNC, X1, X2, X3, X4) \
FUNC(_TEM_LIST1, _PAD_LIST1, _RAW_LIST1, _Comma, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_2(FUNC, X1, X2, X3, X4) \
FUNC(_TEM_LIST2, _PAD_LIST2, _RAW_LIST2, _Comma, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_3(FUNC, X1, X2, X3, X4) \
FUNC(_TEM_LIST3, _PAD_LIST3, _RAW_LIST3, _Comma, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_4(FUNC, X1, X2, X3, X4) \
FUNC(_TEM_LIST4, _PAD_LIST4, _RAW_LIST4, _Comma, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_5(FUNC, X1, X2, X3, X4) \
FUNC(_TEM_LIST5, _PAD_LIST5, _RAW_LIST5, _Comma, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_6(FUNC, X1, X2, X3, X4) \
FUNC(_TEM_LIST6, _PAD_LIST6, _RAW_LIST6, _Comma, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_7(FUNC, X1, X2, X3, X4) \
FUNC(_TEM_LIST7, _PAD_LIST7, _RAW_LIST7, _Comma, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_8(FUNC, X1, X2, X3, X4) \
FUNC(_TEM_LIST8, _PAD_LIST8, _RAW_LIST8, _Comma, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_9(FUNC, X1, X2, X3, X4) \
FUNC(_TEM_LIST9, _PAD_LIST9, _RAW_LIST9, _Comma, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_10(FUNC, X1, X2, X3, X4) \
FUNC(_TEM_LIST10, _PAD_LIST10, _RAW_LIST10, _Comma, X1, X2, X3, X4)

// alternate form for NxN expansion
#define _VARIADIC_EXPAND_ALT_0(FUNC, X1, X2, X3, X4) \
FUNC(_TEM_LIST0, _PAD_LIST0, _RAW_LIST0, , X1, X2, X3, X4)

#define _VARIADIC_EXPAND_ALT_1(FUNC, X1, X2, X3, X4) \
FUNC(_TEM_LIST1, _PAD_LIST1, _RAW_LIST1, _Comma, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_ALT_2(FUNC, X1, X2, X3, X4) \
FUNC(_TEM_LIST2, _PAD_LIST2, _RAW_LIST2, _Comma, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_ALT_3(FUNC, X1, X2, X3, X4) \
FUNC(_TEM_LIST3, _PAD_LIST3, _RAW_LIST3, _Comma, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_ALT_4(FUNC, X1, X2, X3, X4) \
FUNC(_TEM_LIST4, _PAD_LIST4, _RAW_LIST4, _Comma, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_ALT_5(FUNC, X1, X2, X3, X4) \
FUNC(_TEM_LIST5, _PAD_LIST5, _RAW_LIST5, _Comma, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_ALT_6(FUNC, X1, X2, X3, X4) \
FUNC(_TEM_LIST6, _PAD_LIST6, _RAW_LIST6, _Comma, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_ALT_7(FUNC, X1, X2, X3, X4) \
FUNC(_TEM_LIST7, _PAD_LIST7, _RAW_LIST7, _Comma, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_ALT_8(FUNC, X1, X2, X3, X4) \
FUNC(_TEM_LIST8, _PAD_LIST8, _RAW_LIST8, _Comma, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_ALT_9(FUNC, X1, X2, X3, X4) \
FUNC(_TEM_LIST9, _PAD_LIST9, _RAW_LIST9, _Comma, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_ALT_A(FUNC, X1, X2, X3, X4) \
FUNC(_TEM_LIST10, _PAD_LIST10, _RAW_LIST10, _Comma, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_25(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_2(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_3(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_4(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_5(FUNC, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_26(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_25(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_6(FUNC, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_27(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_26(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_7(FUNC, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_28(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_27(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_8(FUNC, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_29(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_28(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_9(FUNC, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_2A(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_29(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_10(FUNC, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_ALT_05(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_ALT_0(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_ALT_1(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_ALT_2(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_ALT_3(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_ALT_4(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_ALT_5(FUNC, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_ALT_06(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_ALT_05(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_ALT_6(FUNC, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_ALT_07(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_ALT_06(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_ALT_7(FUNC, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_ALT_08(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_ALT_07(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_ALT_8(FUNC, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_ALT_09(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_ALT_08(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_ALT_9(FUNC, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_ALT_0A(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_ALT_09(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_ALT_A(FUNC, X1, X2, X3, X4)

	// for 0-X args
#define _VARIADIC_EXPAND_0X(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_0(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_1X(FUNC, X1, X2, X3, X4)

#define _VARIADIC_EXPAND_1X(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_1(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_2X(FUNC, X1, X2, X3, X4)

	// for extra list, one element shorter
#define _VARIADIC_EXPAND_P1_0(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_0(FUNC, X1, X2, _RAW_LIST0, ) \

#define _VARIADIC_EXPAND_P1_1(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_1(FUNC, X1, X2, _RAW_LIST0, ) \

#define _VARIADIC_EXPAND_P1_25(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_2(FUNC, X1, X2, _RAW_LIST1, _Comma) \
	_VARIADIC_EXPAND_3(FUNC, X1, X2, _RAW_LIST2, _Comma) \
	_VARIADIC_EXPAND_4(FUNC, X1, X2, _RAW_LIST3, _Comma) \
	_VARIADIC_EXPAND_5(FUNC, X1, X2, _RAW_LIST4, _Comma)

#define _VARIADIC_EXPAND_P1_26(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_P1_25(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_6(FUNC, X1, X2, _RAW_LIST5, _Comma)

#define _VARIADIC_EXPAND_P1_27(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_P1_26(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_7(FUNC, X1, X2, _RAW_LIST6, _Comma)

#define _VARIADIC_EXPAND_P1_28(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_P1_27(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_8(FUNC, X1, X2, _RAW_LIST7, _Comma)

#define _VARIADIC_EXPAND_P1_29(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_P1_28(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_9(FUNC, X1, X2, _RAW_LIST8, _Comma)

#define _VARIADIC_EXPAND_P1_2A(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_P1_29(FUNC, X1, X2, X3, X4) \
	_VARIADIC_EXPAND_10(FUNC, X1, X2, _RAW_LIST9, _Comma)

	// VARIADIC DOUBLE LOOPS
// call FUNC(TEMPLATE_LIST1, PADDING_LIST1, LIST1, COMMA1,
// TEMPLATE_LIST2, PADDING_LIST2, LIST2, COMMA2)

	// for (0-X, 0) args
#define _VARIADIC_EXPAND_0X_0(FUNC) \
	_VARIADIC_EXPAND_0X(FUNC, _TEM_LIST0, _PAD_LIST0, _RAW_LIST0, ) \

	// for (??, 1-X) args
#define _VARIADIC_EXPAND_XX_11(FUNC, EXPAND) \
	EXPAND(FUNC, _TEM_LIST1, _PAD_LIST1, _RAW_LIST1, _Comma)

#define _VARIADIC_EXPAND_XX_12(FUNC, EXPAND) \
	_VARIADIC_EXPAND_XX_11(FUNC, EXPAND) \
	EXPAND(FUNC, _TEM_LIST2, _PAD_LIST2, _RAW_LIST2, _Comma)

#define _VARIADIC_EXPAND_XX_13(FUNC, EXPAND) \
	_VARIADIC_EXPAND_XX_12(FUNC, EXPAND) \
	EXPAND(FUNC, _TEM_LIST3, _PAD_LIST3, _RAW_LIST3, _Comma)

#define _VARIADIC_EXPAND_XX_14(FUNC, EXPAND) \
	_VARIADIC_EXPAND_XX_13(FUNC, EXPAND) \
	EXPAND(FUNC, _TEM_LIST4, _PAD_LIST4, _RAW_LIST4, _Comma)

#define _VARIADIC_EXPAND_XX_15(FUNC, EXPAND) \
	_VARIADIC_EXPAND_XX_14(FUNC, EXPAND) \
	EXPAND(FUNC, _TEM_LIST5, _PAD_LIST5, _RAW_LIST5, _Comma)

#define _VARIADIC_EXPAND_XX_16(FUNC, EXPAND) \
	_VARIADIC_EXPAND_XX_15(FUNC, EXPAND) \
	EXPAND(FUNC, _TEM_LIST6, _PAD_LIST6, _RAW_LIST6, _Comma)

#define _VARIADIC_EXPAND_XX_17(FUNC, EXPAND) \
	_VARIADIC_EXPAND_XX_16(FUNC, EXPAND) \
	EXPAND(FUNC, _TEM_LIST7, _PAD_LIST7, _RAW_LIST7, _Comma)

#define _VARIADIC_EXPAND_XX_18(FUNC, EXPAND) \
	_VARIADIC_EXPAND_XX_17(FUNC, EXPAND) \
	EXPAND(FUNC, _TEM_LIST8, _PAD_LIST8, _RAW_LIST8, _Comma)

#define _VARIADIC_EXPAND_XX_19(FUNC, EXPAND) \
	_VARIADIC_EXPAND_XX_18(FUNC, EXPAND) \
	EXPAND(FUNC, _TEM_LIST9, _PAD_LIST9, _RAW_LIST9, _Comma)

#define _VARIADIC_EXPAND_XX_1A(FUNC, EXPAND) \
	_VARIADIC_EXPAND_XX_19(FUNC, EXPAND) \
	EXPAND(FUNC, _TEM_LIST10, _PAD_LIST10, _RAW_LIST10, _Comma)

	// for (n-X, n-X) args
#define _VARIADIC_EXPAND_0X_0X(FUNC) \
	_VARIADIC_EXPAND_0X_0(FUNC) \
	_VARIADIC_EXPAND_0_1X(FUNC) \
	_VARIADIC_EXPAND_1X_1X(FUNC)

#define _VARIADIC_EXPAND_1X_1X(FUNC) \
	_VARIADIC_EXPAND_XX_1X(FUNC, _VARIADIC_EXPAND_1X)

	// template lists for functions with no leading parameter
#define _TEM_LIST0(MAP)

#define _TEM_LIST1(MAP) \
	template<MAP(0)>

#define _TEM_LIST2(MAP) \
	template<MAP(0) _COMMA MAP(1)>

#define _TEM_LIST3(MAP) \
	template<MAP(0) _COMMA MAP(1) _COMMA MAP(2)>

#define _TEM_LIST4(MAP) \
	template<MAP(0) _COMMA MAP(1) _COMMA MAP(2) _COMMA MAP(3)>

#define _TEM_LIST5(MAP) \
	template<MAP(0) _COMMA MAP(1) _COMMA MAP(2) _COMMA MAP(3) \
	_COMMA MAP(4)>

#define _TEM_LIST6(MAP) \
	template<MAP(0) _COMMA MAP(1) _COMMA MAP(2) _COMMA MAP(3) \
	_COMMA MAP(4) _COMMA MAP(5)>

#define _TEM_LIST7(MAP) \
	template<MAP(0) _COMMA MAP(1) _COMMA MAP(2) _COMMA MAP(3) \
	_COMMA MAP(4) _COMMA MAP(5) _COMMA MAP(6)>

#define _TEM_LIST8(MAP) \
	template<MAP(0) _COMMA MAP(1) _COMMA MAP(2) _COMMA MAP(3) \
	_COMMA MAP(4) _COMMA MAP(5) _COMMA MAP(6) _COMMA MAP(7)>

#define _TEM_LIST9(MAP) \
	template<MAP(0) _COMMA MAP(1) _COMMA MAP(2) _COMMA MAP(3) \
	_COMMA MAP(4) _COMMA MAP(5) _COMMA MAP(6) _COMMA MAP(7) \
	_COMMA MAP(8)>

#define _TEM_LIST10(MAP) \
	template<MAP(0) _COMMA MAP(1) _COMMA MAP(2) _COMMA MAP(3) \
	_COMMA MAP(4) _COMMA MAP(5) _COMMA MAP(6) _COMMA MAP(7) \
	_COMMA MAP(8) _COMMA MAP(9)>

	// diagonal, for (1-Y, 1-Z) args, Y+Z <= X
#define _VARIADIC_EXPAND_15_1D(FUNC) \
	_VARIADIC_EXPAND_1(FUNC, _TEM_LIST1, _PAD_LIST1, _RAW_LIST1, _Comma) \
	_VARIADIC_EXPAND_1(FUNC, _TEM_LIST2, _PAD_LIST2, _RAW_LIST2, _Comma) \
	_VARIADIC_EXPAND_1(FUNC, _TEM_LIST3, _PAD_LIST3, _RAW_LIST3, _Comma) \
	_VARIADIC_EXPAND_1(FUNC, _TEM_LIST4, _PAD_LIST4, _RAW_LIST4, _Comma) \
	_VARIADIC_EXPAND_2(FUNC, _TEM_LIST1, _PAD_LIST1, _RAW_LIST1, _Comma) \
	_VARIADIC_EXPAND_2(FUNC, _TEM_LIST2, _PAD_LIST2, _RAW_LIST2, _Comma) \
	_VARIADIC_EXPAND_2(FUNC, _TEM_LIST3, _PAD_LIST3, _RAW_LIST3, _Comma) \
	_VARIADIC_EXPAND_3(FUNC, _TEM_LIST1, _PAD_LIST1, _RAW_LIST1, _Comma) \
	_VARIADIC_EXPAND_3(FUNC, _TEM_LIST2, _PAD_LIST2, _RAW_LIST2, _Comma) \
	_VARIADIC_EXPAND_4(FUNC, _TEM_LIST1, _PAD_LIST1, _RAW_LIST1, _Comma)

#define _VARIADIC_EXPAND_16_1D(FUNC) \
	_VARIADIC_EXPAND_15_1D(FUNC) \
	_VARIADIC_EXPAND_1(FUNC, _TEM_LIST5, _PAD_LIST5, _RAW_LIST5, _Comma) \
	_VARIADIC_EXPAND_2(FUNC, _TEM_LIST4, _PAD_LIST4, _RAW_LIST4, _Comma) \
	_VARIADIC_EXPAND_3(FUNC, _TEM_LIST3, _PAD_LIST3, _RAW_LIST3, _Comma) \
	_VARIADIC_EXPAND_4(FUNC, _TEM_LIST2, _PAD_LIST2, _RAW_LIST2, _Comma) \
	_VARIADIC_EXPAND_5(FUNC, _TEM_LIST1, _PAD_LIST1, _RAW_LIST1, _Comma)

#define _VARIADIC_EXPAND_17_1D(FUNC) \
	_VARIADIC_EXPAND_16_1D(FUNC) \
	_VARIADIC_EXPAND_1(FUNC, _TEM_LIST6, _PAD_LIST6, _RAW_LIST6, _Comma) \
	_VARIADIC_EXPAND_2(FUNC, _TEM_LIST5, _PAD_LIST5, _RAW_LIST5, _Comma) \
	_VARIADIC_EXPAND_3(FUNC, _TEM_LIST4, _PAD_LIST4, _RAW_LIST4, _Comma) \
	_VARIADIC_EXPAND_4(FUNC, _TEM_LIST3, _PAD_LIST3, _RAW_LIST3, _Comma) \
	_VARIADIC_EXPAND_5(FUNC, _TEM_LIST2, _PAD_LIST2, _RAW_LIST2, _Comma) \
	_VARIADIC_EXPAND_6(FUNC, _TEM_LIST1, _PAD_LIST1, _RAW_LIST1, _Comma)

#define _VARIADIC_EXPAND_18_1D(FUNC) \
	_VARIADIC_EXPAND_17_1D(FUNC) \
	_VARIADIC_EXPAND_1(FUNC, _TEM_LIST7, _PAD_LIST7, _RAW_LIST7, _Comma) \
	_VARIADIC_EXPAND_2(FUNC, _TEM_LIST6, _PAD_LIST6, _RAW_LIST6, _Comma) \
	_VARIADIC_EXPAND_3(FUNC, _TEM_LIST5, _PAD_LIST5, _RAW_LIST5, _Comma) \
	_VARIADIC_EXPAND_4(FUNC, _TEM_LIST4, _PAD_LIST4, _RAW_LIST4, _Comma) \
	_VARIADIC_EXPAND_5(FUNC, _TEM_LIST3, _PAD_LIST3, _RAW_LIST3, _Comma) \
	_VARIADIC_EXPAND_6(FUNC, _TEM_LIST2, _PAD_LIST2, _RAW_LIST2, _Comma) \
	_VARIADIC_EXPAND_7(FUNC, _TEM_LIST1, _PAD_LIST1, _RAW_LIST1, _Comma)

#define _VARIADIC_EXPAND_19_1D(FUNC) \
	_VARIADIC_EXPAND_18_1D(FUNC) \
	_VARIADIC_EXPAND_1(FUNC, _TEM_LIST8, _PAD_LIST8, _RAW_LIST8, _Comma) \
	_VARIADIC_EXPAND_2(FUNC, _TEM_LIST7, _PAD_LIST7, _RAW_LIST7, _Comma) \
	_VARIADIC_EXPAND_3(FUNC, _TEM_LIST6, _PAD_LIST6, _RAW_LIST6, _Comma) \
	_VARIADIC_EXPAND_4(FUNC, _TEM_LIST5, _PAD_LIST5, _RAW_LIST5, _Comma) \
	_VARIADIC_EXPAND_5(FUNC, _TEM_LIST4, _PAD_LIST4, _RAW_LIST4, _Comma) \
	_VARIADIC_EXPAND_6(FUNC, _TEM_LIST3, _PAD_LIST3, _RAW_LIST3, _Comma) \
	_VARIADIC_EXPAND_7(FUNC, _TEM_LIST2, _PAD_LIST2, _RAW_LIST2, _Comma) \
	_VARIADIC_EXPAND_8(FUNC, _TEM_LIST1, _PAD_LIST1, _RAW_LIST1, _Comma)

#define _VARIADIC_EXPAND_1A_1D(FUNC) \
	_VARIADIC_EXPAND_19_1D(FUNC) \
	_VARIADIC_EXPAND_1(FUNC, _TEM_LIST9, _PAD_LIST9, _RAW_LIST9, _Comma) \
	_VARIADIC_EXPAND_2(FUNC, _TEM_LIST8, _PAD_LIST8, _RAW_LIST8, _Comma) \
	_VARIADIC_EXPAND_3(FUNC, _TEM_LIST7, _PAD_LIST7, _RAW_LIST7, _Comma) \
	_VARIADIC_EXPAND_4(FUNC, _TEM_LIST6, _PAD_LIST6, _RAW_LIST6, _Comma) \
	_VARIADIC_EXPAND_5(FUNC, _TEM_LIST5, _PAD_LIST5, _RAW_LIST5, _Comma) \
	_VARIADIC_EXPAND_6(FUNC, _TEM_LIST4, _PAD_LIST4, _RAW_LIST4, _Comma) \
	_VARIADIC_EXPAND_7(FUNC, _TEM_LIST3, _PAD_LIST3, _RAW_LIST3, _Comma) \
	_VARIADIC_EXPAND_8(FUNC, _TEM_LIST2, _PAD_LIST2, _RAW_LIST2, _Comma) \
	_VARIADIC_EXPAND_9(FUNC, _TEM_LIST1, _PAD_LIST1, _RAW_LIST1, _Comma)

	// padding lists
#define _PAD_LIST0_0(MAP) \
	MAP(0)

#define _PAD_LIST0_1(MAP) \
	MAP(0) _COMMA MAP(1)

#define _PAD_LIST0_2(MAP) \
	MAP(0) _COMMA MAP(1) _COMMA MAP(2)

#define _PAD_LIST0_3(MAP) \
	MAP(0) _COMMA MAP(1) _COMMA MAP(2) _COMMA MAP(3)

#define _PAD_LIST0_4(MAP) \
	MAP(0) _COMMA MAP(1) _COMMA MAP(2) _COMMA MAP(3) _COMMA \
	MAP(4)

#define _PAD_LIST0_5(MAP) \
	MAP(0) _COMMA MAP(1) _COMMA MAP(2) _COMMA MAP(3) _COMMA \
	MAP(4) _COMMA MAP(5)

#define _PAD_LIST0_6(MAP) \
	MAP(0) _COMMA MAP(1) _COMMA MAP(2) _COMMA MAP(3) _COMMA \
	MAP(4) _COMMA MAP(5) _COMMA MAP(6)

#define _PAD_LIST0_7(MAP) \
	MAP(0) _COMMA MAP(1) _COMMA MAP(2) _COMMA MAP(3) _COMMA \
	MAP(4) _COMMA MAP(5) _COMMA MAP(6) _COMMA MAP(7)

#define _PAD_LIST0_8(MAP) \
	MAP(0) _COMMA MAP(1) _COMMA MAP(2) _COMMA MAP(3) _COMMA \
	MAP(4) _COMMA MAP(5) _COMMA MAP(6) _COMMA MAP(7) _COMMA \
	MAP(8)

#define _PAD_LIST0_9(MAP) \
	MAP(0) _COMMA MAP(1) _COMMA MAP(2) _COMMA MAP(3) _COMMA \
	MAP(4) _COMMA MAP(5) _COMMA MAP(6) _COMMA MAP(7) _COMMA \
	MAP(8) _COMMA MAP(9)

#define _PAD_LIST0_10(MAP) \
	MAP(0) _COMMA MAP(1) _COMMA MAP(2) _COMMA MAP(3) _COMMA \
	MAP(4) _COMMA MAP(5) _COMMA MAP(6) _COMMA MAP(7) _COMMA \
	MAP(8) _COMMA MAP(9) _COMMA MAP(10)

	// plain lists
#define _RAW_LIST0(MAP)

#define _RAW_LIST1(MAP) \
	MAP(0)

#define _RAW_LIST2(MAP) \
	MAP(0) _COMMA MAP(1)

#define _RAW_LIST3(MAP) \
	MAP(0) _COMMA MAP(1) _COMMA MAP(2)

#define _RAW_LIST4(MAP) \
	MAP(0) _COMMA MAP(1) _COMMA MAP(2) _COMMA MAP(3)

#define _RAW_LIST5(MAP) \
	MAP(0) _COMMA MAP(1) _COMMA MAP(2) _COMMA MAP(3) \
	_COMMA MAP(4)

#define _RAW_LIST6(MAP) \
	MAP(0) _COMMA MAP(1) _COMMA MAP(2) _COMMA MAP(3) \
	_COMMA MAP(4) _COMMA MAP(5)

#define _RAW_LIST7(MAP) \
	MAP(0) _COMMA MAP(1) _COMMA MAP(2) _COMMA MAP(3) \
	_COMMA MAP(4) _COMMA MAP(5) _COMMA MAP(6)

#define _RAW_LIST8(MAP) \
	MAP(0) _COMMA MAP(1) _COMMA MAP(2) _COMMA MAP(3) \
	_COMMA MAP(4) _COMMA MAP(5) _COMMA MAP(6) _COMMA MAP(7)

#define _RAW_LIST9(MAP) \
	MAP(0) _COMMA MAP(1) _COMMA MAP(2) _COMMA MAP(3) \
	_COMMA MAP(4) _COMMA MAP(5) _COMMA MAP(6) _COMMA MAP(7) \
	_COMMA MAP(8)

#define _RAW_LIST10(MAP) \
	MAP(0) _COMMA MAP(1) _COMMA MAP(2) _COMMA MAP(3) \
	_COMMA MAP(4) _COMMA MAP(5) _COMMA MAP(6) _COMMA MAP(7) \
	_COMMA MAP(8) _COMMA MAP(9)

	// variant calling sequences
#define _VARIADIC_CALL_OPT_X1(FUNC, X1, X2, X3, X4, \
	CALL_OPT, X6, X7, X8) \
		FUNC(X1, X2, X3, X4, CALL_OPT, X6, X7, X8)
#define _VARIADIC_CALL_OPT_X2(FUNC, X1, X2, X3, X4, \
	CALL_OPT, X6, X7, X8) \
		FUNC(X1, X2, X3, X4, CALL_OPT, X6, X7, X8)

	// MAP functions
#define _VAR_VAL(NUM)	\
	_V ## NUM
#define _VAR_TYPE(NUM)	\
	_V ## NUM ## _t
#define _CLASS_TYPE(NUM)	\
	class _VAR_TYPE(NUM)

#define _VAR_VALX(NUM)	\
	_Vx ## NUM
#define _VAR_TYPEX(NUM)	\
	_Vx ## NUM ## _t
#define _CLASS_TYPEX(NUM)	\
	class _VAR_TYPEX(NUM)

#define _CLASS_TYPE_TYPEX(NUM)	\
	class _VAR_TYPE(NUM) _COMMA class _VAR_TYPEX(NUM)

#define _CLASS_NIL(NUM)	\
	class = _Nil
#define _CLASS_TYPE_NIL(NUM)	\
	class _VAR_TYPE(NUM) = _Nil
#define _NIL_PAD(NUM)	\
	_Nil

#define _ARG(NUM) \
	_VAR_VAL(NUM)
#define _ARGX(NUM) \
	_VAR_VALX(NUM)
#define _DECLVAL(NUM)	\
	_STD declval<_VAR_TYPE(NUM)>()
#define _DECAY_COPY_FORWARD_ARG(NUM)	\
	_Decay_copy(_STD forward<_TYPE(NUM)>(_VAR_VAL(NUM)))
#define _REMOVE_REF(NUM)	\
	typename remove_reference<_TYPE(NUM)>::type&
#define _UNREFWRAP_TYPE(NUM)	\
	typename _Unrefwrap<_TYPE(NUM)>::type

#define _ELEMENT_ARG(NUM)	\
	_STD get<NUM>(_Tpl1)
#define _FORWARD_ARG(NUM)	\
	_STD forward<_VAR_TYPE(NUM)>(_VAR_VAL(NUM))
#define _FORWARD_ELEMENT_ARG(NUM)	\
	_STD get<NUM>(_STD forward<decltype(_Tpl1)>(_Tpl1))

#define _ELEMENT_ARGX(NUM)	\
	_STD get<NUM>(_Tpl2)
#define _FORWARD_ARGX(NUM)	\
	_STD forward<_VAR_TYPEX(NUM)>(_VAR_VALX(NUM))
#define _FORWARD_ELEMENT_ARGX(NUM)	\
	_STD get<NUM>(_STD forward<decltype(_Tpl2)>(_Tpl2))

#define _TYPE(NUM) \
	_VAR_TYPE(NUM)
#define _TYPE_REF(NUM)	\
	_VAR_TYPE(NUM)&
#define _TYPE_REFREF(NUM)	\
	_VAR_TYPE(NUM) _REFREF
#define _TYPE_LVALREF(NUM)	\
	_VAR_TYPE(NUM) _LVALREF
#define _TYPE_VALREF(NUM)	\
	_VAR_TYPE(NUM) _VALREF

#define _CONST_TYPE_REF(NUM)	\
	const _TYPE(NUM)&
#define _TYPE_ARG(NUM) \
	_VAR_TYPE(NUM) _VAR_VAL(NUM)
#define _TYPE_REF_ARG(NUM)	\
	_TYPE_REF(NUM) _VAR_VAL(NUM)
#define _TYPE_REFREF_ARG(NUM)	\
	_TYPE_REFREF(NUM) _VAR_VAL(NUM)
#define _TYPE_LVALREF_ARG(NUM)	\
	_TYPE_LVALREF(NUM) _VAR_VAL(NUM)
#define _TYPE_VALREF_ARG(NUM)	\
	_TYPE_VALREF(NUM) _VAR_VAL(NUM)
#define _CONST_TYPE_REF_ARG(NUM)	\
	const _TYPE(NUM)& _VAR_VAL(NUM)

#define _TYPEX(NUM) \
	_VAR_TYPEX(NUM)
#define _TYPEX_REF(NUM)	\
	_VAR_TYPEX(NUM)&
#define _TYPEX_REFREF(NUM)	\
	_VAR_TYPEX(NUM) _REFREF
#define _CONST_TYPEX_REF(NUM)	\
	const _TYPEX(NUM)&
#define _TYPEX_ARG(NUM) \
	_VAR_TYPEX(NUM) _VAR_VALX(NUM)
#define _TYPEX_REF_ARG(NUM)	\
	_TYPEX_REF(NUM) _VAR_VALX(NUM)
#define _TYPEX_REFREF_ARG(NUM)	\
	_TYPEX_REFREF(NUM) _VAR_VALX(NUM)
#define _CONST_TYPEX_REF_ARG(NUM)	\
	const _TYPEX(NUM)& _VAR_VALX(NUM)
#define _DECAY_TYPEX(NUM) \
	typename decay<_TYPEX(NUM)>::type

// NB: Need an extra class to avoid specializing initial template declaration
#define _MAX_CLASS_LIST	\
	_PAD_LIST0(_CLASS_TYPE_NIL) _COMMA class = _Nil
#define _MAX_NIL_CLASS_LIST	\
	_PAD_LIST0(_CLASS_NIL) _COMMA class = _Nil
#define _MAX_NIL_LIST	\
	_PAD_LIST0(_NIL_PAD) _COMMA _Nil
#define _MAX_ALIST \
	_PAD_LIST0(_TYPE)

_STD_BEGIN
		// TEMPLATE CLASS _Sizeof
template<class = _Nil, _MAX_CLASS_LIST>
	struct _Sizeof;

template<>
	struct _Sizeof<_Nil, _MAX_NIL_LIST>
	{	// no parameters
	static const size_t value = 0;
	};

#define _CLASS_SIZEOF( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
template<class _Ty _EX(C) LIST(_CLASS_TYPE)> \
	struct _Sizeof<_Ty _EX(C) LIST(_TYPE), PADDING_LIST(_NIL_PAD)> \
	{	/* get length of LIST(_TYPE) from smaller */ \
	static const size_t value = 1 + _Sizeof<LIST(_TYPE)>::value; \
	};

_VARIADIC_EXPAND_0X(_CLASS_SIZEOF, , , , )
#undef _CLASS_SIZEOF
_STD_END
 #endif /* _HAS_VARIADIC_TEMPLATES */

_STD_BEGIN
	// TEMPLATE CLASS _Arg_types
template<class... _Types>
	struct _Arg_types
	{	// provide argument_type, etc. (sometimes)
	};

template<class _Ty1>
	struct _Arg_types<_Ty1>
	{	// provide argument_type, etc. (sometimes)
	typedef _Ty1 argument_type;
	};

template<class _Ty1,
	class _Ty2>
	struct _Arg_types<_Ty1, _Ty2>
	{	// provide argument_type, etc. (sometimes)
	typedef _Ty1 first_argument_type;
	typedef _Ty2 second_argument_type;
	};

	// TEMPLATE CLASS is_function
template<class _Ty>
	struct _Is_function
	{	// determine whether _Ty is a function
	typedef false_type _Bool_type;
	};

#define _IS_FUNCTION(CALL_OPT) \
template<class _Ret, \
	class... _Types> \
	struct _Is_function<_Ret CALL_OPT (_Types...)> \
		: _Arg_types<_Types...> \
	{	/* determine whether _Ty is a function */ \
	typedef true_type _Bool_type; \
	typedef _Ret result_type; \
	};

_NON_MEMBER_CALL(_IS_FUNCTION)
#undef _IS_FUNCTION

template<class _Ret,
	class... _Types>
	struct _Is_function<_Ret (_Types..., ...)>
	{	// no calling conventions for ellipsis
	typedef true_type _Bool_type;
	typedef _Ret result_type;
	};

template<class _Ty>
	struct is_function
		: _Is_function<_Ty>::_Bool_type
	{	// determine whether _Ty is a function
	};

		// TEMPLATE FUNCTION addressof
template<class _Ty> inline
	_Ty *_Addressof(_Ty& _Val, true_type) _NOEXCEPT
	{	// return address of function _Val
	return (_Val);
	}

template<class _Ty> inline
	_Ty *_Addressof(_Ty& _Val, false_type) _NOEXCEPT
	{	// return address of object _Val
	return (reinterpret_cast<_Ty *>(
		&const_cast<char&>(
		reinterpret_cast<const volatile char&>(_Val))));
	}

template<class _Ty> inline
	_Ty *addressof(_Ty& _Val) _NOEXCEPT
	{	// return address of _Val
	return (_Addressof(_Val, is_function<_Ty>()));
	}
_STD_END
#endif /* _XSTDDEF_ */

/*
 * Copyright (c) by P.J. Plauger. All rights reserved.
 * Consult your license regarding permissions and restrictions.
V6.50:1422 */
